// DISCoHAsH 512 - crypto hash 
// https://github.com/dosyago/discohash
//   Copyright 2023 Cris Stringfellow & The Dosyago Corporation
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
#include <cstdio>
#include <inttypes.h>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>
#include "discohash.h"

constexpr int STATE = 64;
constexpr int STATEM = STATE-1;
constexpr int STATE64 = STATE >> 3;
constexpr int HSTATE64 = STATE64 >> 1;
constexpr int STATE64M = STATE64-1;
constexpr int HSTATE64M = HSTATE64-1;
alignas(uint64_t) uint8_t disco_c_buf[STATE] = {0};
constexpr uint64_t P = 0xFFFFFFFFFFFFFFFF - 58;
constexpr uint64_t Q = UINT64_C(13166748625691186689);
alignas(uint64_t) uint8_t *dcs8 = (uint8_t *)disco_c_buf;
uint64_t *dcs = (uint64_t *)disco_c_buf;

static inline uint64_t
rot (uint64_t v, int n)
{
  n = n & 63U;
  if (n)
    v = (v >> n) | (v << (64 - n));
  return v;
}

static inline uint8_t
rot8 (uint8_t v, int n)
{
  n = n & 7U;
  if (n)
    v = (v >> n) | (v << (8 - n));
  return v;
}

static inline void
mix (const int A)
{
  const int B = A + 1;
  dcs[A] *= P;
  dcs[A] = rot (dcs[A], 23);
  dcs[A] *= Q;

  dcs[B] ^= dcs[A];

  dcs[B] *= P;
  dcs[B] = rot (dcs[B], 23);
  dcs[B] *= Q;
}

static inline void
round (const uint64_t *m64, const uint8_t *m8, int len)
{
  int index = 0;
  int sindex = 0;
  uint64_t counter = 0xfaccadaccad09997;
  uint8_t counter8 = 137;

  for (int Len = len >> 3; index < Len; index++)
    {
      dcs[sindex] += rot (m64[index] + index + counter + 1, 23);
      counter += ~m64[index] + 1;
      switch (sindex)
        {
        case 1:
          mix (0);
          sindex++;
          break;
        case 3:
          mix (2);
          sindex++;
          break;
        case 5:
          mix (4);
          sindex++;
          break;
        case 7:
          mix (6);
          sindex = 0;
          break;
        default:
          sindex++;
          break;
        }
    }

  mix (1);
  mix (3);
  mix (5);

  index <<= 3;
  sindex = index & (STATEM);
  for (; index < len; index++)
    {
      dcs8[sindex] += rot8 (m8[index] + index + counter8 + 1, 23);
      counter8 += ~m8[index] + 1;
      mix (index % STATE64M);
      if (sindex >= STATEM)
        {
          sindex = 0;
        }
      else
        {
          sindex++;
        }
    }

  mix (0);
  mix (1);
  mix (2);
  mix (3);
  mix (4);
  mix (5);
  mix (6);
}

void
DISCoHAsH_512_64 (const void *key, int len, seed_t seed, void *out)
{
  int tempLen = len;
  if (tempLen == 0)
    {
      tempLen = 1;
    }
  alignas (uint64_t) uint8_t *tempBuf = new uint8_t[tempLen];
  const uint8_t *key8Arr = (uint8_t *)key;

  alignas (uint64_t) const uint8_t seedbuf[16] = { 0 };
  const uint8_t *seed8Arr = (uint8_t *)seedbuf;
  const uint64_t *seed64Arr = (uint64_t *)seedbuf;
  uint32_t *seed32Arr = (uint32_t *)seedbuf;

  // the cali number from the Matrix (1999)
  seed32Arr[0] = UINT32_C (0xc5550690);
  seed32Arr[0] -= seed;
  seed32Arr[1] = 1 + seed;
  seed32Arr[2] = ~(1 - seed);
  seed32Arr[3] = (1 + seed) * UINT32_C (0xf00dacca);

  // nothing up my sleeve
  dcs[0] = UINT64_C (0x123456789abcdef0);
  dcs[1] = UINT64_C (0x0fedcba987654321);
  dcs[2] = UINT64_C (0xaccadacca80081e5);
  dcs[3] = UINT64_C (0xf00baaf00f00baaa);
  dcs[4] = UINT64_C (0xbeefdeadbeefc0de);
  dcs[5] = UINT64_C (0xabad1deafaced00d);
  dcs[6] = UINT64_C (0xfaceb00cfacec0de);
  dcs[7] = UINT64_C (0xdeadc0dedeadbeef);

  memcpy (tempBuf, key, len);
  uint64_t *temp64 = reinterpret_cast<uint64_t *> (tempBuf);

  round (temp64, key8Arr, len);
  round (seed64Arr, seed8Arr, 16);
  round (dcs, dcs8, STATE);

  // 512-bit internal state 256-bit output
  uint64_t h[4] = { 0 }; // This will hold the final output

  h[0] -= dcs[2];
  h[0] -= dcs[3];
  h[0] -= dcs[6];
  h[0] -= dcs[7];

  // full 256-bit output
  /*
    h[1] = dcs[2] ^ dcs[3] ^ dcs[6] ^ dcs[7];

    h[2] -= dcs[0];
    h[2] -= dcs[1];
    h[2] -= dcs[4];
    h[2] -= dcs[5];

    h[3] = dcs[0] ^ dcs[1] ^ dcs[4] ^ dcs[5];
  */

  memcpy (out, h, sizeof (h) / 4); // divide by 4 as smhasher only uses 64 bits

  delete[] tempBuf;
}

static bool DISCoHAsH_512_64_bad_seeds(std::vector<uint32_t> &seeds)
{
  seeds = std::vector<uint32_t>{
    0x00005147, 0x00009dce, 0x0000addc, 0x0000f64c, 0x0001234d, 0x0001386a,
    0x0001544c, 0x000197b1, 0x0001df9b, 0x0002182a, 0x000257af, 0x00028019,
    0x00028839, 0x0002a8b2, 0x00034caa, 0x00035af6, 0x000362d3, 0x00039631,
    0x0003a13a, 0x00041f7b, 0x00042a98, 0x00043626, 0x0004524b, 0x000482bc,
    0x0004c41b, 0x0004d588, 0x000557ad, 0x0005cadb, 0x0005f12c, 0x00060a9d,
    0x00060b5d, 0x00060dc7, 0x000681db, 0x0006910a, 0x000698d5, 0x00069d47,
    0x0006d93d, 0x0007273b, 0x00073173, 0x00074132, 0x00079281, 0x0007b868,
    0x0007bd26, 0x0007cb12, 0x0007d6c9, 0x0007e120, 0x0007e688, 0x0007ecd2,
    0x00080cd7, 0x00082be9, 0x0008428f, 0x000894a7, 0x00089a2c, 0x0008cf9a,
    0x0008e2e8, 0x00090ad1, 0x00093d70, 0x0009619e, 0x000970e8, 0x0009719e,
    0x000991ed, 0x00099be2, 0x0009e91a, 0x0009f62c, 0x000a033a, 0x000a1d30,
    0x000a2d09, 0x000a5abd, 0x000a8c6f, 0x000a961f, 0x000abb8a, 0x000af673,
    0x000afdd3, 0x000b4df6, 0x000b7938, 0x000b8170, 0x000b85d5, 0x000bb044,
    0x000bc3b8, 0x000be910, 0x000bf47b, 0x000c8470, 0x000c8f28, 0x000ca8aa,
    0x000cd474, 0x000ce76e, 0x000cf886, 0x000d0c25, 0x000d1ebe, 0x000d5e51,
    0x000d5f08, 0x000d60a0, 0x000da456, 0x000ddb68, 0x000e1534, 0x000e255f,
    0x000e4c04, 0x000e51c4, 0x000e547f, 0x000e5d12, 0x000e61d7, 0x000e7505,
    0x000e8234, 0x000e94e8, 0x000e9653, 0x000e9b28, 0x000eb735, 0x000ebdba,
    0x000edac6, 0x000ee22b, 0x000ee5c0, 0x000efbd3, 0x000f1ac5, 0x000f56f1,
    0x000f5f6d, 0x000f71e7, 0x000f8433, 0x000f8867, 0x000f9e8e, 0x000faeaf,
    0x000fc0f4, 0x000fc2ed, 0x000fda04, 0x001026a8, 0x00116fb8, 0x00118ca7,
    0x0011bb38, 0x0011c93d, 0x0011cbf3, 0x0011db12, 0x00121231, 0x001214aa,
    0x00122028, 0x00124573, 0x00125810, 0x0012705c, 0x00127c86, 0x00127e0b,
    0x00128a5a, 0x0012995c, 0x00129ae0, 0x00130462, 0x001309ab, 0x00130ad2,
    0x00131823, 0x00133fec, 0x001343d2, 0x00135156, 0x001356a5, 0x001368fe,
    0x00138114, 0x00138890, 0x0013b6dc, 0x00140246, 0x0014361f, 0x00143d38,
    0x00146e38, 0x0014a506, 0x00150656, 0x00151938, 0x0015280c, 0x001534af,
    0x0015376a, 0x0015448e, 0x00155693, 0x001599dd, 0x00159e34, 0x0015aaab,
    0x0015bafb, 0x0015bbe2, 0x0015e154, 0x0016019e, 0x00160937, 0x00162e42,
    0x00163818, 0x00166122, 0x00166225, 0x00166651, 0x00167e5c, 0x00168936,
    0x0016b32d, 0x0016c929, 0x0016d06f, 0x0016d8f8, 0x0016da2c, 0x0016e95d,
    0x001700a9, 0x00174024, 0x00178c04, 0x0017927b, 0x0017a316, 0x0017a41c,
    0x0017aae1, 0x0017f268, 0x0017f2fd, 0x0017f987, 0x00183bae, 0x00185ebd,
    0x001896e7, 0x0018d123, 0x0018f445, 0x001907dd, 0x00190bb7, 0x001910ca,
    0x00191988, 0x001937a3, 0x00194280, 0x00195c1a, 0x00196d7d, 0x0019a7bc,
    0x0019c1a5, 0x0019c9fb, 0x0019d6b1, 0x001a1330, 0x001a13ba, 0x001a2917,
    0x001a64ed, 0x001a8678, 0x001a93a6, 0x001aa0c4, 0x001ab083, 0x001ab846,
    0x001ad969, 0x001ae64c, 0x001aef4f, 0x001b12ef, 0x001b450a, 0x001b58f1,
    0x001b66de, 0x001b6878, 0x001b697e, 0x001b6aad, 0x001b8232, 0x001bc138,
    0x001bcc45, 0x001bd59a, 0x001be45a, 0x001c0d8a, 0x001c11ee, 0x001c2248,
    0x001c59db, 0x001c66c4, 0x001c76b7, 0x001cb80e, 0x001cfa7a, 0x001d0113,
    0x001d2055, 0x001d22fc, 0x001d28af, 0x001d39ca, 0x001d55ed, 0x001d7c56,
    0x001d90e4, 0x001db1e3, 0x001dc49b, 0x001de007, 0x001defcb, 0x001e56e4,
    0x001ebc43, 0x001ec709, 0x001f20e9, 0x001f2d04, 0x001f486d, 0x001f5b16,
    0x001f6517, 0x001f74b3, 0x001f798a, 0x001f999f, 0x001faeb7, 0x001fba4c,
    0x001fd67c, 0x001fe250, 0x001ffdff, 0x00201485, 0x00204319, 0x00207364,
    0x0020a30c, 0x0020d17f, 0x00212a0a, 0x00212fbd, 0x00214482, 0x002144bc,
    0x0021715a, 0x002209f5, 0x002239f2, 0x002268fc, 0x0022818f, 0x002296ab,
    0x0022d331, 0x00230e75, 0x00231f4b, 0x00232aee, 0x002333ac, 0x00233bb3,
    0x0023421e, 0x002346d0, 0x00235931, 0x00236038, 0x00236bbb, 0x00236c84,
    0x00237143, 0x400013fb, 0x400065a9, 0x400117b8, 0x40017010, 0x40018bea,
    0x4001b98d, 0x40027773, 0x400294b1, 0x4002acc2, 0x4002bbb6, 0x4002e78c,
    0x4002fa5f, 0x40030511, 0x40031770, 0x40033494, 0x400358df, 0x4003601b,
    0x40036590, 0x400374bd, 0x4003888f, 0x4003c1a1, 0x40040479, 0x400411ae,
    0x400483ac, 0x400502c8, 0x4005047c, 0x400520ee, 0x400564de, 0x40059b6e,
    0x4005b889, 0x4005c53f, 0x4005d721, 0x400627ff, 0x400632df, 0x40068083,
    0x4006a517, 0x4006cdb7, 0x4006fa8c, 0x40070633, 0x40070e32, 0x40077929,
    0x4007d1cf, 0x4007f49a, 0x40085624, 0x40086c79, 0x4008b859, 0x4008bad0,
    0x4008c9f7, 0x40091efc, 0x40099d1f, 0x4009a801, 0x4009aafd, 0x4009b959,
    0x4009bb45, 0x4009bd6e, 0x4009ff59, 0x400a0644, 0x400a1b7d, 0x400a3b86,
    0x400a492a, 0x400abf91, 0x400ac273, 0x400af479, 0x400afa6a, 0x400aff24,
    0x400b5089, 0x400b5e9e, 0x400b657d, 0x400b798e, 0x400b9e39, 0x400bb9f4,
    0x400be161, 0x400be921, 0x400beef6, 0x400bf2c6, 0x400c009a, 0x400c098f,
    0x400c0f67, 0x400c114e, 0x400c3750, 0x400c4560, 0x400c49f2, 0x400c4afb,
    0x400c7822, 0x400cd2b3, 0x400ceb50, 0x400cfe9d, 0x400d45d0, 0x400d4acb,
    0x400d80a0, 0x400dae36, 0x400db4a7, 0x400e2ea7, 0x400e58f1, 0x400e6cb5,
    0x400e6f35, 0x400ebd7a, 0x400ece86, 0x400edfe8, 0x400ee715, 0x400f0cee,
    0x400f0f67, 0x400f3bc7, 0x400f7b1c, 0x400fbef2, 0x400ff22b, 0x4010639b,
    0x401067f2, 0x40106a58, 0x401077a9, 0x401090b3, 0x4010fa2d, 0x40110c72,
    0x40111a33, 0x40118242, 0x40119190, 0x4011a914, 0x4011c299, 0x401209d5,
    0x40123fa3, 0x40127711, 0x401287d1, 0x40129994, 0x40130bec, 0x40137fab,
    0x40141fc0, 0x40142fe3, 0x4014489f, 0x401455d4, 0x40145df5, 0x4014711b,
    0x40147e95, 0x401485ff, 0x401489d1, 0x4014b3b1, 0x4014dd05, 0x4014ed3a,
    0x4014f649, 0x4014fbfb, 0x401533d6, 0x40154da1, 0x4015660c, 0x40158369,
    0x40159805, 0x4015dce8, 0x4016506e, 0x4016c9ed, 0x4016d897, 0x4016f1c3,
    0x4017196c, 0x40171c02, 0x40171ce6, 0x401724f2, 0x40172662, 0x40173793,
    0x40174123, 0x4017571e, 0x40182cc7, 0x401847c7, 0x40185159, 0x401879cf,
    0x40187cf0, 0x40189dff, 0x4018ae45, 0x4018e199, 0x4018e1bd, 0x4018e2c8,
    0x4018f1e4, 0x4018f823, 0x40193849, 0x40193f61, 0x40195504, 0x40199e83,
    0x4019cf6b, 0x4019d192, 0x4019f37b, 0x401a3aa4, 0x401a9622, 0x401aa36a,
    0x401ac5ab, 0x401ad1fe, 0x401ae425, 0x401b0578, 0x401b0b26, 0x401b0d3c,
    0x401b268f, 0x401b54bc, 0x401b5e0f, 0x401b74db, 0x401b7c5e, 0x401bb11e,
    0x401bd868, 0x401be38a, 0x401c0d0e, 0x401c1c68, 0x401c2021, 0x401c505f,
    0x401c5578, 0x401c7978, 0x401c8f6b, 0x401cad06, 0x401cad98, 0x401cbf26,
    0x401ccd2b, 0x401d1fb1, 0x401d294f, 0x401d992b, 0x401dc1b4, 0x401dcdd5,
    0x401ddee0, 0x401de157, 0x401e0a26, 0x401e380c, 0x401e4147, 0x401e45f8,
    0x401e8f0e, 0x401e93c5, 0x401ed3a6, 0x401ed436, 0x401ed4ae, 0x401ed67a,
    0x401ed744, 0x401eee15, 0x401f2cc8, 0x401f3990, 0x401f3f1c, 0x401f5919,
    0x401f93f0, 0x401f9afb, 0x401f9d3c, 0x401faf16, 0x401fba5f, 0x401ffacd,
    0x401ffc18, 0x401ffdec, 0x402003e9, 0x40208461, 0x40209832, 0x4020d845,
    0x40213a29, 0x402141c3, 0x402189f3, 0x402190e9, 0x4021f4cc, 0x40221a6e,
    0x40225aab, 0x40228a4d, 0x4022eb6c, 0x4022f27b, 0x402318c6, 0x4023399c,
    0x402366ec, 0x80000d31, 0x80003adc, 0x80005c6c, 0x800066df, 0x80008a14,
    0x8000be0d, 0x800100c8, 0x800104c1, 0x80010f6c, 0x8001143d, 0x800144d3,
    0x8001621d, 0x80016bb7, 0x800177db, 0x8001ce99, 0x8001d03f, 0x8001e475,
    0x8001f830, 0x80021011, 0x80022f7f, 0x80029ee8, 0x8002ee1f, 0x800330e8,
    0x80033363, 0x80033f5c, 0x80037095, 0x8003ad6e, 0x8003ffb8, 0x800410dd,
    0x80051821, 0x8005436b, 0x80055643, 0x80055974, 0x8005a00f, 0x8005cef5,
    0x8005da53, 0x8005eba6, 0x80061318, 0x8006299f, 0x80064c9d, 0x80069539,
    0x8006ab92, 0x8006e5e6, 0x80070643, 0x80076c52, 0x8007a94d, 0x8007c758,
    0x800824ff, 0x80087b6c, 0x8008f159, 0x8008f811, 0x80099e09, 0x800a93d2,
    0x800ad48d, 0x800afea0, 0x800b62b7, 0x800b6430, 0x800b6643, 0x800bb083,
    0x800bc7e4, 0x800bf3c6, 0x800bf7bc, 0x800c024f, 0x800c43da, 0x800c55a8,
    0x800ceba7, 0x800cf4b5, 0x800cf79a, 0x800d0cc7, 0x800d0e8c, 0x800d10f8,
    0x800d1c32, 0x800d35f8, 0x800d3ffd, 0x800d58a1, 0x800d799c, 0x800d8fbe,
    0x800dbe9d, 0x800dc0e4, 0x800dde4a, 0x800de7ef, 0x800deaff, 0x800dfabc,
    0x800e13de, 0x800e36a9, 0x800e3b36, 0x800e4e42, 0x800e62d1, 0x800e7763,
    0x800e829f, 0x800e9571, 0x800e9a81, 0x800eda48, 0x800ef3d2, 0x800f3349,
    0x800f5267, 0x800f8650, 0x800fa485, 0x800fb6b5, 0x800fc328, 0x800fdbcd,
    0x800fe447, 0x800fed11, 0x80108eef, 0x8010e28c, 0x8010f5e5, 0x801171f3,
    0x8011a36f, 0x8011a56c, 0x8011b6bb, 0x8011e77d, 0x801211fa, 0x80121d11,
    0x8012346d, 0x8012655b, 0x80126d34, 0x80127c20, 0x8012901e, 0x8012c8aa,
    0x8012d6c2, 0x8012f8c0, 0x80133047, 0x801337a0, 0x801355d5, 0x801364c1,
    0x8013e126, 0x801411f0, 0x8014dcc5, 0x801501d8, 0x8015140c, 0x8015201e,
    0x80152f54, 0x8015964e, 0x8015b004, 0x8015e1a1, 0x8015f218, 0x80162f04,
    0x80163be0, 0x80164737, 0x8016662b, 0x8016baca, 0x8016d770, 0x8016e0e3,
    0x80173df7, 0x80173ec1, 0x8017459a, 0x80179fd5, 0x8017a0d3, 0x80180289,
    0x80183c8d, 0x80185afb, 0x8018ebf8, 0x80190c16, 0x80190ddb, 0x8019146e,
    0x80195746, 0x80195fa4, 0x80196371, 0x80196964, 0x80196b75, 0x8019ab5d,
    0x8019ba6f, 0x8019bb7d, 0x8019d3d4, 0x801a3a45, 0x801a3d4f, 0x801a6c06,
    0x801a9c0d, 0x801ab817, 0x801ac20a, 0x801ac932, 0x801acbd5, 0x801af29b,
    0x801b02fc, 0x801b17bd, 0x801b2adb, 0x801b55f6, 0x801b6be2, 0x801b832d,
    0x801b89dc, 0x801bba7c, 0x801bddbf, 0x801bf464, 0x801c0a5f, 0x801c650d,
    0x801caef0, 0x801d0cd6, 0x801d23e3, 0x801d391c, 0x801d4d8a, 0x801d8c1a,
    0x801d99f5, 0x801e12e8, 0x801e1a3b, 0x801e24b9, 0x801ec0fd, 0x801ecd6f,
    0x801ed0e8, 0x801f1c8c, 0x801f62ac, 0x801f6fa5, 0x801f9d21, 0x801fae1c,
    0x801fb0a1, 0x801fbc32, 0x801fdc31, 0x801fede6, 0x801ff11a, 0x8020169e,
    0x80201bea, 0x8020244b, 0x80207a7c, 0x8020a9cb, 0x8020ad01, 0x8020bc30,
    0x8020c68d, 0x8020eaaf, 0x8020f941, 0x802109c4, 0x8021191d, 0x8021254e,
    0x80215953, 0x80215d62, 0x8021815f, 0x80218af0, 0x80219843, 0x8021c4f8,
    0x8021c580, 0x8021c85f, 0x8021e1c8, 0x8021e6ad, 0x8021fe7e, 0x80223287,
    0x80225e31, 0x8022646f, 0x80226f19, 0x80228a6c, 0x8022afaf, 0x8022e8a3,
    0x80235a95, 0x8023f7ff, 0xc0001942, 0xc0003977, 0xc000806d, 0xc000cf1b,
    0xc000e41f, 0xc00129c9, 0xc0012ad4, 0xc0015d86, 0xc001aba8, 0xc001cc92,
    0xc00209f8, 0xc00258ab, 0xc0027878, 0xc002cbd4, 0xc00312ea, 0xc00316ce,
    0xc0031b36, 0xc0034c99, 0xc003589c, 0xc003823f, 0xc003a5c8, 0xc003c160,
    0xc003e5fd, 0xc0040bf1, 0xc004107c, 0xc00429d9, 0xc0043043, 0xc004cf30,
    0xc004d8d2, 0xc004de03, 0xc0053ebc, 0xc005578f, 0xc0058021, 0xc005965e,
    0xc005b580, 0xc005d7e4, 0xc006a260, 0xc006aad0, 0xc006b1d7, 0xc006c3c2,
    0xc00720d4, 0xc007270a, 0xc0074e0e, 0xc0075b1a, 0xc007605a, 0xc007dc2f,
    0xc0087f05, 0xc0089121, 0xc0089349, 0xc0089a4c, 0xc0089e46, 0xc008af7b,
    0xc008b3a5, 0xc008b6ad, 0xc008e9c2, 0xc008ed86, 0xc0093664, 0xc009662f,
    0xc00969f0, 0xc0096d62, 0xc009ba80, 0xc00a4387, 0xc00a7864, 0xc00a9cd2,
    0xc00aa120, 0xc00ace89, 0xc00aec56, 0xc00b43ee, 0xc00b44e8, 0xc00b632a,
    0xc00b81b6, 0xc00b8db2, 0xc00bcba2, 0xc00bcef0, 0xc00c1fee, 0xc00c2789,
    0xc00c27af, 0xc00c6797, 0xc00c71ec, 0xc00c7a5d, 0xc00c98af, 0xc00d3921,
    0xc00d3b8b, 0xc00d409b, 0xc00d4330, 0xc00dcfd0, 0xc00e04bb, 0xc00e087e,
    0xc00e2e8a, 0xc00e483b, 0xc00e6559, 0xc00e6992, 0xc00e726e, 0xc00ec416,
    0xc00ede5e, 0xc00eea84, 0xc00eeec9, 0xc00f278a, 0xc00f4709, 0xc00fc3a8,
    0xc0103e44, 0xc010ccee, 0xc010cfcc, 0xc0113f3a, 0xc01143e2, 0xc0114770,
    0xc0114906, 0xc0117e7f, 0xc0118642, 0xc011a1d4, 0xc0121a10, 0xc01229bf,
    0xc0125358, 0xc01255e3, 0xc0128754, 0xc012b4e1, 0xc012b645, 0xc012c7e8,
    0xc0132c89, 0xc01336dd, 0xc0139daa, 0xc013aee0, 0xc013b327, 0xc013c1bc,
    0xc013c56a, 0xc013d322, 0xc014141c, 0xc01428d9, 0xc01434ec, 0xc014527d,
    0xc0145e35, 0xc014bb56, 0xc014e458, 0xc015010f, 0xc015543c, 0xc0156424,
    0xc015a7f0, 0xc015bdce, 0xc015c59e, 0xc0164536, 0xc016862a, 0xc0168b40,
    0xc0169eda, 0xc017034a, 0xc0170694, 0xc0170d5d, 0xc017197b, 0xc017387e,
    0xc0175596, 0xc01772ab, 0xc017ba86, 0xc017c127, 0xc017f393, 0xc017f99b,
    0xc0181145, 0xc0183c67, 0xc0183f19, 0xc0187182, 0xc018b1e2, 0xc018c228,
    0xc0190378, 0xc0191a07, 0xc0191ad1, 0xc0191b46, 0xc019319c, 0xc0193887,
    0xc0196029, 0xc01965bd, 0xc0196788, 0xc01967eb, 0xc0197423, 0xc0197fc8,
    0xc019800e, 0xc019c88d, 0xc019fc83, 0xc01a0b02, 0xc01a2b9d, 0xc01aa505,
    0xc01ab79b, 0xc01abb41, 0xc01accad, 0xc01afc67, 0xc01b411d, 0xc01b65c1,
    0xc01b9984, 0xc01c2b0e, 0xc01c2ec6, 0xc01c68b1, 0xc01c7e02, 0xc01c856d,
    0xc01cdb55, 0xc01d5dc6, 0xc01d63e4, 0xc01dede1, 0xc01e002f, 0xc01e0d8d,
    0xc01e419a, 0xc01ee3e5, 0xc01f0088, 0xc01f1f5a, 0xc01f5c46, 0xc01f809e,
    0xc01f8a31, 0xc01fa94c, 0xc01fdbce, 0xc01fedac, 0xc01ff26e, 0xc02000a7,
    0xc0202bfd, 0xc0203f99, 0xc0209815, 0xc020a6f6, 0xc020af7b, 0xc020b308,
    0xc020c14b, 0xc020c7a8, 0xc020d2ed, 0xc0211c97, 0xc0213bf6, 0xc0216aeb,
    0xc0216bf8, 0xc0218d5c, 0xc021b53b, 0xc021dece, 0xc0225758, 0xc0225826,
    0xc0228328, 0xc0229e3a, 0xc022bcf5, 0xc022e66f, 0xc022e852, 0xc022eebc,
    0xc022f4fb, 0xc022f813, 0xc022ffb2, 0xc0235d3d, 0xc0236331
  };
  return true;
}

void DISCoHAsH_512_64_seed_init (uint32_t &seed) {
  std::vector<uint32_t> bad_seeds;
  DISCoHAsH_512_64_bad_seeds(bad_seeds);
  while (std::binary_search(bad_seeds.begin(), bad_seeds.end(), seed))
    seed++;
}
